﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace TTEngine
{
    //是否要分离文件中的资源，和内存中的资源概念,
    //因为发现IO用的资源和内存中使用的资源还是有很大的区别的
    public class Texture2D : IAsset
    {
        public uint AssetTypeID => AssetMgr.ID_Texture2D;
        public FakeUnity.Warp.FrameworkNative.Texture textureNative;
        public bool CanRead
        {
            get;
            private set;
        }

        public bool CanWrite
        {
            get;
            private set;
        }

        //持久化数据
        public byte[] platformData;
    }
    //这些AssetPacker是要分平台的，Texture2DPacker是主要分平台的资源，其它大部分都是通用的
    public class Texture2DPacker : IAssetPacker
    {
        public uint AssetTypeID => AssetMgr.ID_Texture2D;

        public bool ReadOnly => true;

        int GetMaskIndex(uint mask)
        {
            if (mask > 0xffffff)
                return 3;
            if (mask > 0xffff)
                return 2;
            else if (mask > 0xff)
                return 1;
            else
                return 0;
        }
        public IAsset Read(Stream stream, uint length)
        {
            var tag = (byte)stream.ReadByte();
            if (tag == 1)//一个原始图片文件
            {
                byte[] buflen = new byte[4];
                stream.Read(buflen, 0, 4);
                UInt32 len = BitConverter.ToUInt32(buflen, 0);
                byte[] data = new byte[len];
                var pos = stream.Position;
                stream.Read(data, 0, (int)len);
                Texture2D result = null;
                using (var tempms = new System.IO.MemoryStream(data))
                {

                    FreeImageAPI.FREE_IMAGE_FORMAT format = FreeImageAPI.FREE_IMAGE_FORMAT.FIF_UNKNOWN;
                    var bitmap = FreeImageAPI.FreeImage.LoadFromStream(tempms,
                        FreeImageAPI.FREE_IMAGE_LOAD_FLAGS.DEFAULT, ref format);
                    //var bitmapc = FreeImageAPI.FreeImage.ConvertTo32Bits(bitmap);

                    int width = (int)FreeImageAPI.FreeImage.GetWidth(bitmap);
                    int height = (int)FreeImageAPI.FreeImage.GetHeight(bitmap);
                    int pitch = (int)FreeImageAPI.FreeImage.GetPitch(bitmap);
                    var bpp = FreeImageAPI.FreeImage.GetBPP(bitmap) / 8;
                    var rmask = GetMaskIndex(FreeImageAPI.FreeImage.GetRedMask(bitmap));
                    var gmask = GetMaskIndex(FreeImageAPI.FreeImage.GetGreenMask(bitmap));
                    var bmask = GetMaskIndex(FreeImageAPI.FreeImage.GetBlueMask(bitmap));

                    result = new Texture2D();
                    IntPtr mem = System.Runtime.InteropServices.Marshal.AllocHGlobal(width * height * 4);
                    IntPtr srcmem = FreeImageAPI.FreeImage.GetBits(bitmap);
                    unsafe
                    {
                        byte* srcbts = (byte*)srcmem;
                        byte* destbts = (byte*)mem;
                        for (var y = 0; y < height; y++)
                        {
                            for (var x = 0; x < width; x++)
                            {
                                var seek = y * pitch + x * bpp;
                                //翻轉Y
                                var deskseek = ((width - 1 - y) * width + x) * 4;

                                var r = srcbts[seek + rmask];
                                var g = srcbts[seek + gmask];
                                var b = srcbts[seek + bmask];
                                destbts[deskseek + 0] = r;
                                destbts[deskseek + 1] = g;
                                destbts[deskseek + 2] = b;
                                destbts[deskseek + 3] = 255;
                            }
                        }
                    }
                    FreeImageAPI.FreeImage.Unload(bitmap);

                    result.textureNative = FakeUnity.Warp.FrameworkNative.Texture_Create((uint)width, (uint)height, mem);
                }
                stream.Position = pos + len;
                return result;
                // unsafe
                // {
                //     fixed (byte* dataptr = data)
                //     {
                //         IntPtr ptr = new IntPtr(dataptr);
                //         var newtex = new Texture2D();

                //         FreeImageAPI.FreeImage.
                //         newtex.textureNative = FakeUnity.Warp.FrameworkNative.Texture_LoadFromMem(ptr, len);
                //         return newtex;
                //     }
                // }

            }
            else
            {
                throw new Exception("not support yet.");
            }
        }

        public uint Write(IAsset asset, Stream stream)
        {
            throw new NotImplementedException();
        }
    }
}
